home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
eckelt01.zip
/
10
/
BINARY.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-23
|
14KB
|
488 lines
// File from page 406 in "Thinking in C++" by Bruce Eckel
//////////////////////////////////////////////////
// From the compressed package ECKELT01.ZIP 2/21/95
// Copyright (c) Bruce Eckel, 1995
// Source code file from the book "Thinking in C++",
// Prentice Hall, 1995, ISBN: 0-13-917709-4
// All rights reserved EXCEPT as allowed by the following
// statements: You may freely use this file for your own
// work, including modifications and distribution in
// executable form only. You may copy and distribute this
// file, as long as it is only distributed in the complete
// (compressed) package with the other files from this
// book and you do not remove this copyright and notice.
// You may not distribute modified versions of the source
// code in this package. This package may be freely placed
// on bulletin boards, internet nodes, shareware disks and
// product vendor disks. You may not use this file in
// printed media without the express permission of the
// author. Bruce Eckel makes no
// representation about the suitability of this software
// for any purpose. It is provided "as is" without express
// or implied warranty of any kind. The entire risk as to
// the quality and performance of the software is with
// you. Should the software prove defective, you assume
// the cost of all necessary servicing, repair, or
// correction.
// If you think you've found an error, please
// email all modified files with loudly commented changes
// to: eckel@aol.com (please use the same
// address for non-code errors found in the book).
//////////////////////////////////////////////////
//: BINARY.CPP -- Overloading binary operators
#include <fstream.h>
#include "..\allege.h"
ofstream out("binary.out");
class integer { // Combine this with UNARY.CPP
long i;
public:
integer(long I = 0) : i(I) {}
// Operators that create new, modified value:
friend const integer
operator+(const integer& left,
const integer& right);
friend const integer
operator-(const integer& left,
const integer& right);
friend const integer
operator*(const integer& left,
const integer& right);
friend const integer
operator/(const integer& left,
const integer& right);
friend const integer
operator%(const integer& left,
const integer& right);
friend const integer
operator^(const integer& left,
const integer& right);
friend const integer
operator&(const integer& left,
const integer& right);
friend const integer
operator|(const integer& left,
const integer& right);
friend const integer
operator<<(const integer& left,
const integer& right);
friend const integer
operator>>(const integer& left,
const integer& right);
// Assignments modify & return lvalue:
friend integer&
operator+=(integer& left,
const integer& right);
friend integer&
operator-=(integer& left,
const integer& right);
friend integer&
operator*=(integer& left,
const integer& right);
friend integer&
operator/=(integer& left,
const integer& right);
friend integer&
operator%=(integer& left,
const integer& right);
friend integer&
operator^=(integer& left,
const integer& right);
friend integer&
operator&=(integer& left,
const integer& right);
friend integer&
operator|=(integer& left,
const integer& right);
friend integer&
operator>>=(integer& left,
const integer& right);
friend integer&
operator<<=(integer& left,
const integer& right);
// Conditional operators return true/false:
friend int
operator==(const integer& left,
const integer& right);
friend int
operator!=(const integer& left,
const integer& right);
friend int
operator<(const integer& left,
const integer& right);
friend int
operator>(const integer& left,
const integer& right);
friend int
operator<=(const integer& left,
const integer& right);
friend int
operator>=(const integer& left,
const integer& right);
friend int
operator&&(const integer& left,
const integer& right);
friend int
operator||(const integer& left,
const integer& right);
// Write the contents to an ostream:
void print(ostream& os) const { os << i; }
};
const integer
operator+(const integer& left,
const integer& right) {
return integer(left.i + right.i);
}
const integer
operator-(const integer& left,
const integer& right) {
return integer(left.i - right.i);
}
const integer
operator*(const integer& left,
const integer& right) {
return integer(left.i * right.i);
}
const integer
operator/(const integer& left,
const integer& right) {
allege(right.i != 0, "divide by zero");
return integer(left.i / right.i);
}
const integer
operator%(const integer& left,
const integer& right) {
allege(right.i != 0, "modulo by zero");
return integer(left.i % right.i);
}
const integer
operator^(const integer& left,
const integer& right) {
return integer(left.i ^ right.i);
}
const integer
operator&(const integer& left,
const integer& right) {
return integer(left.i & right.i);
}
const integer
operator|(const integer& left,
const integer& right) {
return integer(left.i | right.i);
}
const integer
operator<<(const integer& left,
const integer& right) {
return integer(left.i << right.i);
}
const integer
operator>>(const integer& left,
const integer& right) {
return integer(left.i >> right.i);
}
// Assignments modify & return lvalue:
integer& operator+=(integer& left,
const integer& right) {
if(&left == &right) {/* self-assignment */}
left.i += right.i;
return left;
}
integer& operator-=(integer& left,
const integer& right) {
if(&left == &right) {/* self-assignment */}
left.i -= right.i;
return left;
}
integer& operator*=(integer& left,
const integer& right) {
if(&left == &right) {/* self-assignment */}
left.i *= right.i;
return left;
}
integer& operator/=(integer& left,
const integer& right) {
allege(right.i != 0, "divide by zero");
if(&left == &right) {/* self-assignment */}
left.i /= right.i;
return left;
}
integer& operator%=(integer& left,
const integer& right) {
allege(right.i != 0, "modulo by zero");
if(&left == &right) {/* self-assignment */}
left.i %= right.i;
return left;
}
integer& operator^=(integer& left,
const integer& right) {
if(&left == &right) {/* self-assignment */}
left.i ^= right.i;
return left;
}
integer& operator&=(integer& left,
const integer& right) {
if(&left == &right) {/* self-assignment */}
left.i &= right.i;
return left;
}
integer& operator|=(integer& left,
const integer& right) {
if(&left == &right) {/* self-assignment */}
left.i |= right.i;
return left;
}
integer& operator>>=(integer& left,
const integer& right) {
if(&left == &right) {/* self-assignment */}
left.i >>= right.i;
return left;
}
integer& operator<<=(integer& left,
const integer& right) {
if(&left == &right) {/* self-assignment */}
left.i <<= right.i;
return left;
}
// Conditional operators return true/false:
int operator==(const integer& left,
const integer& right) {
return left.i == right.i;
}
int operator!=(const integer& left,
const integer& right) {
return left.i != right.i;
}
int operator<(const integer& left,
const integer& right) {
return left.i < right.i;
}
int operator>(const integer& left,
const integer& right) {
return left.i > right.i;
}
int operator<=(const integer& left,
const integer& right) {
return left.i <= right.i;
}
int operator>=(const integer& left,
const integer& right) {
return left.i >= right.i;
}
int operator&&(const integer& left,
const integer& right) {
return left.i && right.i;
}
int operator||(const integer& left,
const integer& right) {
return left.i || right.i;
}
void h(integer& c1, integer& c2) {
// A complex expression:
c1 += c1 * c2 + c2 % c1;
#define TRY(op) \
out << "c1 = "; c1.print(out); \
out << ", c2 = "; c2.print(out); \
out << "; c1 " #op " c2 produces ";\
(c1 op c2).print(out); \
out << endl;
TRY(+) TRY(-) TRY(*) TRY(/)
TRY(%) TRY(^) TRY(&) TRY(|)
TRY(<<) TRY(>>) TRY(+=) TRY(-=)
TRY(*=) TRY(/=) TRY(%=) TRY(^=)
TRY(&=) TRY(|=) TRY(>>=) TRY(<<=)
// Conditionals:
#define TRYC(op) \
out << "c1 = "; c1.print(out); \
out << ", c2 = "; c2.print(out); \
out << "; c1 " #op " c2 produces ";\
out << (c1 op c2); \
out << endl;
TRYC(<) TRYC(>) TRYC(==) TRYC(!=) TRYC(<=)
TRYC(>=) TRYC(&&) TRYC(||)
}
// Member operators (implicit "this"):
class byte { // Combine this with UNARY.CPP
unsigned char b;
public:
byte(unsigned char B = 0) : b(B) {}
// No side effects: const member function:
const byte
operator+(const byte& right) const {
return byte(b + right.b);
}
const byte
operator-(const byte& right) const {
return byte(b - right.b);
}
const byte
operator*(const byte& right) const {
return byte(b * right.b);
}
const byte
operator/(const byte& right) const {
allege(right.b != 0, "divide by zero");
return byte(b / right.b);
}
const byte
operator%(const byte& right) const {
allege(right.b != 0, "modulo by zero");
return byte(b % right.b);
}
const byte
operator^(const byte& right) const {
return byte(b ^ right.b);
}
const byte
operator&(const byte& right) const {
return byte(b & right.b);
}
const byte
operator|(const byte& right) const {
return byte(b | right.b);
}
const byte
operator<<(const byte& right) const {
return byte(b << right.b);
}
const byte
operator>>(const byte& right) const {
return byte(b >> right.b);
}
// Assignments modify & return lvalue.
// operator= can only be a member function:
byte& operator=(const byte& right) {
// Handle self-assignment:
if(this == &right) return *this;
b = right.b;
return *this;
}
byte& operator+=(const byte& right) {
if(this == &right) {/* self-assignment */}
b += right.b;
return *this;
}
byte& operator-=(const byte& right) {
if(this == &right) {/* self-assignment */}
b -= right.b;
return *this;
}
byte& operator*=(const byte& right) {
if(this == &right) {/* self-assignment */}
b *= right.b;
return *this;
}
byte& operator/=(const byte& right) {
allege(right.b != 0, "divide by zero");
if(this == &right) {/* self-assignment */}
b /= right.b;
return *this;
}
byte& operator%=(const byte& right) {
allege(right.b != 0, "modulo by zero");
if(this == &right) {/* self-assignment */}
b %= right.b;
return *this;
}
byte& operator^=(const byte& right) {
if(this == &right) {/* self-assignment */}
b ^= right.b;
return *this;
}
byte& operator&=(const byte& right) {
if(this == &right) {/* self-assignment */}
b &= right.b;
return *this;
}
byte& operator|=(const byte& right) {
if(this == &right) {/* self-assignment */}
b |= right.b;
return *this;
}
byte& operator>>=(const byte& right) {
if(this == &right) {/* self-assignment */}
b >>= right.b;
return *this;
}
byte& operator<<=(const byte& right) {
if(this == &right) {/* self-assignment */}
b <<= right.b;
return *this;
}
// Conditional operators return true/false:
int operator==(const byte& right) const {
return b == right.b;
}
int operator!=(const byte& right) const {
return b != right.b;
}
int operator<(const byte& right) const {
return b < right.b;
}
int operator>(const byte& right) const {
return b > right.b;
}
int operator<=(const byte& right) const {
return b <= right.b;
}
int operator>=(const byte& right) const {
return b >= right.b;
}
int operator&&(const byte& right) const {
return b && right.b;
}
int operator||(const byte& right) const {
return b || right.b;
}
// Write the contents to an ostream:
void print(ostream& os) const {
os << "0x" << hex << int(b) << dec;
}
};
void k(byte& b1, byte& b2) {
b1 = b1 * b2 + b2 % b1;
#define TRY2(op) \
out << "b1 = "; b1.print(out); \
out << ", b2 = "; b2.print(out); \
out << "; b1 " #op " b2 produces ";\
(b1 op b2).print(out); \
out << endl;
b1 = 9; b2 = 47;
TRY2(+) TRY2(-) TRY2(*) TRY2(/)
TRY2(%) TRY2(^) TRY2(&) TRY2(|)
TRY2(<<) TRY2(>>) TRY2(+=) TRY2(-=)
TRY2(*=) TRY2(/=) TRY2(%=) TRY2(^=)
TRY2(&=) TRY2(|=) TRY2(>>=) TRY2(<<=)
TRY2(=) // Assignment operator
// Conditionals:
#define TRYC2(op) \
out << "b1 = "; b1.print(out); \
out << ", b2 = "; b2.print(out); \
out << "; b1 " #op " b2 produces ";\
out << (b1 op b2); \
out << endl;
b1 = 9; b2 = 47;
TRYC2(<) TRYC2(>) TRYC2(==) TRYC2(!=) TRYC2(<=)
TRYC2(>=) TRYC2(&&) TRYC2(||)
// Chained assignment:
byte b3 = 92;
b1 = b2 = b3;
}
main() {
integer c1(47), c2(9);
h(c1, c2);
out << "\n member functions:" << endl;
byte b1(47), b2(9);
k(b1, b2);
}